const axios = require('axios');
const fs = require('fs').promises;
const path = require('path');
const logger = require('../utils/logger');

// 配置文件路径
const SETTINGS_FILE = path.join(__dirname, '../data/settings.json');

// OpenWeather API配置
const OPENWEATHER_API_KEY = process.env.OPENWEATHER_API_KEY;
const OPENWEATHER_BASE_URL = 'https://api.openweathermap.org/data/2.5';

// 确保设置文件存在
const ensureSettingsFile = async () => {
  try {
    // 确保目录存在
    const dataDir = path.dirname(SETTINGS_FILE);
    await fs.mkdir(dataDir, { recursive: true });
    
    // 检查文件是否存在
    try {
      await fs.access(SETTINGS_FILE);
    } catch (error) {
      // 文件不存在，创建默认设置文件
      await fs.writeFile(SETTINGS_FILE, JSON.stringify({
        theme: 'light',
        language: 'zh-CN',
        notifications: true,
        weatherCity: '深圳',
        voiceAssistant: true
      }, null, 2));
      logger.info(`创建默认设置文件: ${SETTINGS_FILE}`);
    }
  } catch (error) {
    logger.error(`确保设置文件存在时出错: ${error.message}`);
    throw error;
  }
};

// 读取设置
const readSettings = async () => {
  await ensureSettingsFile();
  
  try {
    const data = await fs.readFile(SETTINGS_FILE, 'utf8');
    return JSON.parse(data);
  } catch (error) {
    logger.error(`读取设置失败: ${error.message}`);
    throw new Error(`读取设置失败: ${error.message}`);
  }
};

// 写入设置
const writeSettings = async (settings) => {
  try {
    await fs.writeFile(SETTINGS_FILE, JSON.stringify(settings, null, 2));
  } catch (error) {
    logger.error(`写入设置失败: ${error.message}`);
    throw new Error(`写入设置失败: ${error.message}`);
  }
};

/**
 * 获取当前天气
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
exports.getCurrentWeather = async (req, res) => {
  try {
    // 检查API密钥是否配置
    if (!OPENWEATHER_API_KEY) {
      return res.status(500).json({
        success: false,
        message: 'OpenWeather API密钥未配置'
      });
    }
    
    // 获取城市参数
    const city = req.query.city;
    if (!city) {
      return res.status(400).json({
        success: false,
        message: '缺少城市参数'
      });
    }
    
    // 调用OpenWeather API
    const response = await axios.get(`${OPENWEATHER_BASE_URL}/weather`, {
      params: {
        q: city,
        appid: OPENWEATHER_API_KEY,
        units: 'metric', // 使用摄氏度
        lang: 'zh_cn' // 中文结果
      }
    });
    
    // 格式化响应数据
    const weatherData = {
      city: response.data.name,
      country: response.data.sys.country,
      temperature: response.data.main.temp,
      feels_like: response.data.main.feels_like,
      humidity: response.data.main.humidity,
      pressure: response.data.main.pressure,
      wind_speed: response.data.wind.speed,
      wind_direction: response.data.wind.deg,
      clouds: response.data.clouds.all,
      weather: {
        id: response.data.weather[0].id,
        main: response.data.weather[0].main,
        description: response.data.weather[0].description,
        icon: response.data.weather[0].icon
      },
      timestamp: new Date(response.data.dt * 1000).toISOString(),
      sunrise: new Date(response.data.sys.sunrise * 1000).toISOString(),
      sunset: new Date(response.data.sys.sunset * 1000).toISOString()
    };
    
    res.json({
      success: true,
      data: weatherData
    });
  } catch (error) {
    logger.error(`获取当前天气失败: ${error.message}`);
    
    // 处理API错误
    if (error.response) {
      const statusCode = error.response.status;
      const errorMessage = error.response.data.message || '未知错误';
      
      if (statusCode === 404) {
        return res.status(404).json({
          success: false,
          message: '未找到指定城市',
          error: errorMessage
        });
      }
      
      return res.status(statusCode).json({
        success: false,
        message: '天气API错误',
        error: errorMessage
      });
    }
    
    // 其他错误
    res.status(500).json({
      success: false,
      message: '获取天气数据失败',
      error: error.message
    });
  }
};

/**
 * 获取天气预报
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
exports.getWeatherForecast = async (req, res) => {
  try {
    // 检查API密钥是否配置
    if (!OPENWEATHER_API_KEY) {
      return res.status(500).json({
        success: false,
        message: 'OpenWeather API密钥未配置'
      });
    }
    
    // 获取参数
    const city = req.query.city;
    if (!city) {
      return res.status(400).json({
        success: false,
        message: '缺少城市参数'
      });
    }
    
    // 获取预报天数（默认5天）
    const days = Math.min(parseInt(req.query.days) || 5, 7);
    
    // 调用OpenWeather API
    const response = await axios.get(`${OPENWEATHER_BASE_URL}/forecast`, {
      params: {
        q: city,
        appid: OPENWEATHER_API_KEY,
        units: 'metric', // 使用摄氏度
        lang: 'zh_cn', // 中文结果
        cnt: days * 8 // 每天8个3小时预报
      }
    });
    
    // 格式化响应数据
    const forecastData = {
      city: response.data.city.name,
      country: response.data.city.country,
      timezone: response.data.city.timezone,
      forecast: response.data.list.map(item => ({
        timestamp: new Date(item.dt * 1000).toISOString(),
        temperature: item.main.temp,
        feels_like: item.main.feels_like,
        humidity: item.main.humidity,
        pressure: item.main.pressure,
        wind_speed: item.wind.speed,
        wind_direction: item.wind.deg,
        clouds: item.clouds.all,
        weather: {
          id: item.weather[0].id,
          main: item.weather[0].main,
          description: item.weather[0].description,
          icon: item.weather[0].icon
        },
        rain: item.rain ? item.rain['3h'] : 0,
        snow: item.snow ? item.snow['3h'] : 0
      }))
    };
    
    res.json({
      success: true,
      data: forecastData
    });
  } catch (error) {
    logger.error(`获取天气预报失败: ${error.message}`);
    
    // 处理API错误
    if (error.response) {
      const statusCode = error.response.status;
      const errorMessage = error.response.data.message || '未知错误';
      
      if (statusCode === 404) {
        return res.status(404).json({
          success: false,
          message: '未找到指定城市',
          error: errorMessage
        });
      }
      
      return res.status(statusCode).json({
        success: false,
        message: '天气API错误',
        error: errorMessage
      });
    }
    
    // 其他错误
    res.status(500).json({
      success: false,
      message: '获取天气预报失败',
      error: error.message
    });
  }
};

/**
 * 获取默认城市的天气
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
exports.getDefaultWeather = async (req, res) => {
  try {
    // 读取设置获取默认城市
    const settings = await readSettings();
    const defaultCity = settings.weatherCity || '深圳';
    
    // 重定向到当前天气API
    req.query.city = defaultCity;
    return exports.getCurrentWeather(req, res);
  } catch (error) {
    logger.error(`获取默认天气失败: ${error.message}`);
    res.status(500).json({
      success: false,
      message: '获取默认天气失败',
      error: error.message
    });
  }
};

/**
 * 设置默认城市
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
exports.setDefaultCity = async (req, res) => {
  try {
    const { city } = req.body;
    
    if (!city || city.trim() === '') {
      return res.status(400).json({
        success: false,
        message: '城市名称不能为空'
      });
    }
    
    // 验证城市是否有效（通过调用天气API）
    try {
      await axios.get(`${OPENWEATHER_BASE_URL}/weather`, {
        params: {
          q: city,
          appid: OPENWEATHER_API_KEY,
          units: 'metric'
        }
      });
    } catch (apiError) {
      if (apiError.response && apiError.response.status === 404) {
        return res.status(400).json({
          success: false,
          message: '无效的城市名称'
        });
      }
      throw apiError;
    }
    
    // 更新设置
    const settings = await readSettings();
    settings.weatherCity = city;
    await writeSettings(settings);
    
    res.json({
      success: true,
      message: '默认城市已更新',
      data: {
        city
      }
    });
  } catch (error) {
    logger.error(`设置默认城市失败: ${error.message}`);
    res.status(500).json({
      success: false,
      message: '设置默认城市失败',
      error: error.message
    });
  }
};